from app01.utils.bootstrap import BootStrapModelForm
from django import forms
from app01 import models
from django.core.exceptions import ValidationError
from app01.utils.bootstrap import BootStrapModelForm
from app01.utils.encrypt import md5


class UserModelForm(BootStrapModelForm):
    name = forms.CharField(min_length=2, label="用户名")
    password = forms.CharField(min_length=6, label="密码")  # validators=正则表达式

    class Meta:
        model = models.UserInfo
        # 展示字段
        # fields="__all__"  展示所有字段
        # exclude=["level"] 展示除“level”字段
        fields = ["name", "password", "age", "account", "create_time", "depart", "gender"]

        # 前端html样式控制
        #
        # 1.机械写法逐个该样式
        # widgets={
        #     "name":forms.TextInput(attrs={"class":"form-control"}),
        #     "password":forms.PasswordInput(attrs={"class":"form-control"})
        # }
        #
        # 2.重新定义init方法，执行父类的init方法

    # def __init__(self, *args, **kwargs):
    #     super().__init__(*args, **kwargs)
    #     # 3.循环拿到所有field字段插件，给所有的字段加上{"class":"form_control"}
    #     for name, field in self.fields.items():
    #         # ??? 修改密码样式如何做?
    #         # if name == "creat_time":
    #         #     field.widget.attrs = {"type": "Date"}
    #         # if name == "password":
    #         #     field.widget.attrs = {"class": "form-control", "type": "Password"}
    #         field.widget.attrs = {"class": "form-control", "placeholder": field.label}


class NumModelForm(BootStrapModelForm):
    # 验证：方法1
    mobile = forms.CharField(
        label="手机号",
        # validators=正则表达式 校验规则
        # validators=[RegexValidator(r'^1\d{10}$', '手机号格式错误'), ]
    )
    price = forms.DecimalField(label="价格")

    class Meta:
        model = models.PrettyNum
        fields = ["mobile", "price", "level", "status"]

    # def __init__(self, *args, **kwargs):
    #     super().__init__(*args, **kwargs)
    #     for name, field in self.fields.items():
    #         field.widget.attrs = {"class": "form-control", "placeholder": field.label}

    # 验证：方法2
    # clean_字段名，钩子方法
    def clean_mobile(self):
        # 输入值给text_mobile
        text_mobile = self.cleaned_data["mobile"]
        mobile_is_exist = models.PrettyNum.objects.filter(mobile=text_mobile).exists()
        if mobile_is_exist:
            raise ValidationError("号码已存在")
        if len(text_mobile) != 11:
            # 验证通过，显示提示
            raise ValidationError("格式错误")
        # 验证失败，返回输入值
        return text_mobile


class PrettyEditModelForm(BootStrapModelForm):
    mobile = forms.CharField(label="手机号")  # ,disabled=True   mobile改为不可修改
    price = forms.DecimalField(label="价格")

    class Meta:
        model = models.PrettyNum
        # 不写 ”mobile“ 不出现手机号这行
        fields = ["mobile", "price", "level", "status"]

    # def __init__(self, *args, **kwargs):
    #     super().__init__(*args, **kwargs)
    #     for name, field in self.fields.items():
    #         field.widget.attrs = {"class": "form-control", "placeholder": field.label}

    def clean_mobile(self):

        text_mobile = self.cleaned_data["mobile"]

        # self.instance.pk 当前编辑行的 ID，主键primary_key=id
        # .exclude(id=xx) 排除xx
        mobile_is_exist = models.PrettyNum.objects.exclude(id=self.instance.pk).filter(mobile=text_mobile).exists()

        if mobile_is_exist:
            raise ValidationError("号码已存在")
        if len(text_mobile) != 11:
            # 验证通过，显示提示
            raise ValidationError("格式错误")
        # 验证失败，返回输入值
        return text_mobile


class AdminModelForm(BootStrapModelForm):
    confirm_password = forms.CharField(label="确认密码",
                                       widget=forms.PasswordInput(render_value=True), )

    class Meta:
        model = models.Admin
        # 按顺序处理 元数据名字前面加clean_xx
        fields = ["username", "password", "confirm_password"]
        widgets = {
            "password": forms.PasswordInput(render_value=True),
        }

    def clean_password(self):
        password = self.cleaned_data.get('password')
        return md5(password)  # 密码加密，返回给password字段

    # 钩子，密码是否一致
    def clean_confirm_password(self):
        password = self.cleaned_data.get('password')
        confirm = md5(self.cleaned_data.get('confirm_password'))  # 确认密码md5加密
        if password != confirm:
            raise ValidationError("密码不一致！")
        return confirm
        # return 意义：数据库中confirm_password字段被改为return的值


class AdminEditModelForm(BootStrapModelForm):
    class Meta:
        model = models.Admin
        fields = ['username']


class AdminResetModelForm(BootStrapModelForm):
    confirm_password = forms.CharField(label="确认密码",
                                       widget=forms.PasswordInput(render_value=True), )

    class Meta:
        model = models.Admin
        fields = ['password', 'confirm_password']
        widgets = {
            "password": forms.PasswordInput(render_value=True),
        }

    def clean_password(self):
        password = self.cleaned_data.get('password')
        md5_password = md5(password)
        exists = models.Admin.objects.filter(id=self.instance.pk, password=md5_password).exists()
        if exists:
            raise ValidationError("密码不能与原密码相同！")
        return md5(password)  # 密码加密，返回给password字段

    # 钩子，密码是否一致
    def clean_confirm_password(self):
        password = self.cleaned_data.get('password')
        confirm = md5(self.cleaned_data.get('confirm_password'))  # 确认密码md5加密
        if password != confirm:
            raise ValidationError("密码不一致！")
        return confirm
        # return 意义：数据库中confirm_password字段被改为return的值


class CityModelForm(BootStrapModelForm):
    bootstrap_exclude_field = ['img']

    class Meta:
        model = models.City
        fields = "__all__"
